package com.mlink.ai.chat.ads;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;

import androidx.annotation.Nullable;

import com.adsdk.android.ads.OxAdSdkManager;
import com.adsdk.android.ads.constants.AdEvents;
import com.google.android.gms.ads.AdValue;
import com.google.gson.Gson;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 广告价值打点
 */
public class OxAdValueUtils {


    private static final String TAG = "OxAdValue";

    private static final String FILE_NAME = "MavlADSDK_sp";//  本地存储的file名字

    public final static double AD_UNIT_VALUE = 1000000;

    public final static String S_USER_REVENUE = "Ad_User_Revenue";

    public final static String PREF_IAA_VALUE = "pref_iaa_value";
    public final static String PREF_IAA_LAST_TIME = "pref_iaa_last_time";
    public final static String PREF_IAA_LTV_VALUE = "pref_iaa_ltv_value";
    public final static String PREF_TaichiTroasCache = "pref_TaichiTroasCache";

    public static final String PARAM_KEY_VALUE = "value";
    public static final String PARAM_KEY_CURRENCY = "currency";
    public static final String PARAM_KEY_REVENUE = "revenue";
    public static final String PARAM_KEY_NETWORK_NAME = "networkName";
    public static final String PARAM_KEY_AD_UNIT_IDENTIFIER = "adUnitIdentifier";
    public static final String PARAM_KEY_PLACEMENT = "placement";
    public static final String PARAM_KEY_NETWORK_PLACEMENT = "networkPlacement";
    public static final String PARAM_KEY_CREATIVE_IDENTIFIER = "creativeIdentifier";
    public static final String PARAM_KEY_ADFORMAT = "adformat";
    public static final String PARAM_KEY_COUNTRY = "country";
    public static final String PARAM_KEY_AD_PLATFORM = "ad_platform";
    public static final String PARAM_KEY_PRECISION_TYPE = "precisionType";
    public static final String PARAM_KEY_ADNETWORK = "adNetwork";
    public static final String PARAM_KEY_PLACEMENT_ID = "placement_id";
    public static final String PARAM_KEY_AD_FORMAT = "ad_format";
    public static final String PARAM_KEY_CORE_LEVEL = "core_level";
    public static final String AD_PLATFORM_ADMOB = "AdMob";
    public static final String AD_PLATFORM_MAX = "MAX";

    public static void logAdmobImpressionRevenue(String adUnitId, String adFormat, String adNetwork, AdValue adValue, @Nullable String placement) {
        // Log(收集)每一次广告的价值到Firebase
        Bundle bundle = new Bundle();
        double revenue = (double) adValue.getValueMicros() / AD_UNIT_VALUE;
        bundle.putDouble(PARAM_KEY_VALUE, revenue);
        bundle.putDouble(PARAM_KEY_REVENUE, revenue);
        bundle.putString(PARAM_KEY_PLACEMENT, placement);
        // getValueMicros() returns the value of the adin micro units.
        // For example, agetValueMicros() return value of 5,000
        // means the ad is estimated to be worth$0.005.
        // adValue.getCurrencyCode(): 直接设置为USD。
        bundle.putString(PARAM_KEY_CURRENCY, "USD");
        // Optional
        bundle.putString(PARAM_KEY_PRECISION_TYPE,
                String.valueOf(adValue.getPrecisionType())
        );
        //(Optional) 记录PrecisionType
        bundle.putString(PARAM_KEY_ADNETWORK, adNetwork);//(Optional) 记录adNetwork
        bundle.putString(PARAM_KEY_PLACEMENT_ID, adUnitId);
        bundle.putString(PARAM_KEY_AD_FORMAT, adFormat);
        bundle.putString(PARAM_KEY_AD_PLATFORM, AD_PLATFORM_ADMOB);
        AdEventUtil.trackAdEvent(AdEvents.EVENT_AD_IMPRESSION_REVENUE, bundle);
        recorderIaaValue(OxAdSdkManager.getInstance().getContext(), adValue.getValueMicros());
    }

    /**
     * This method should be invoked in the API: "ad impression data" to record the impression revenue.
     *
     * @param context:  Context
     * @param iaaValue: The ad impression revenue.
     * @Method: recorderIaaValue
     * @Author: ZXD
     * @Date: 5/13/21 12:15 PM
     */
    private static void recorderIaaValue(Context context, long iaaValue) {
        long currentDayIaaValue = getLong(context, PREF_IAA_VALUE, 0);

        long targetIaaValue = iaaValue;

        if (isSameDay(context)) {
            if ((Long.MAX_VALUE - currentDayIaaValue) < iaaValue) {
                targetIaaValue = Long.MAX_VALUE;
            } else {
                targetIaaValue = currentDayIaaValue + iaaValue;
            }
        } else {
            saveIaaValueLtv(context, null);
        }

        saveLong(context, PREF_IAA_VALUE, targetIaaValue);
        logLtvValue(context, targetIaaValue);
        LogTaichiTroasValue(context, iaaValue);
    }

    private static void logLtvValue(Context context, long oneDayValue) {
        double[] firebaseConfigValues = OxRemoteConfigHelper.getTopValuesConfig();
        double top10ValueD = firebaseConfigValues[0];
        double top20ValueD = firebaseConfigValues[1];
        double top30ValueD = firebaseConfigValues[2];
        double top40ValueD = firebaseConfigValues[3];
        double top50ValueD = firebaseConfigValues[4];
        double top60ValueD = firebaseConfigValues[5];

        if (oneDayValue > 0) {

            IaaValueLtv iaaValueLtv = getIaaValueLtv(context);

            Bundle bundle = new Bundle();
            bundle.putDouble(S_USER_REVENUE, ((double) oneDayValue / AD_UNIT_VALUE));
            bundle.putDouble("value", ((double) oneDayValue / AD_UNIT_VALUE));
            bundle.putDouble("revenue", ((double) oneDayValue / AD_UNIT_VALUE));
            bundle.putString("currency", "USD");
            if (top60ValueD != 0.0D && oneDayValue > top60ValueD * AD_UNIT_VALUE && iaaValueLtv.isTop60()) {
                AdEventUtil.trackAdEvent(AdEvents.EVENT_TOP60, bundle);
                iaaValueLtv.setTop60(false);
                saveIaaValueLtv(context, iaaValueLtv);

            }
            if (top50ValueD != 0.0D && oneDayValue > top50ValueD * AD_UNIT_VALUE && iaaValueLtv.isTop50()) {
                AdEventUtil.trackAdEvent(AdEvents.EVENT_TOP50, bundle);
                iaaValueLtv.setTop50(false);
                saveIaaValueLtv(context, iaaValueLtv);

            }
            if (top40ValueD != 0.0D && oneDayValue > top40ValueD * AD_UNIT_VALUE && iaaValueLtv.isTop40()) {
                AdEventUtil.trackAdEvent(AdEvents.EVENT_TOP40, bundle);
                iaaValueLtv.setTop40(false);
                saveIaaValueLtv(context, iaaValueLtv);

            }
            if (top30ValueD != 0.0D && oneDayValue > top30ValueD * AD_UNIT_VALUE && iaaValueLtv.isTop30()) {
                AdEventUtil.trackAdEvent(AdEvents.EVENT_TOP30, bundle);
                iaaValueLtv.setTop30(false);
                saveIaaValueLtv(context, iaaValueLtv);
                AdEventUtil.logFacebookEvent(AdEvents.EVENT_TOP30, bundle);
            }
            if (top20ValueD != 0.0D && oneDayValue > top20ValueD * AD_UNIT_VALUE && iaaValueLtv.isTop20()) {
                AdEventUtil.trackAdEvent(AdEvents.EVENT_TOP20, bundle);
                iaaValueLtv.setTop20(false);
                saveIaaValueLtv(context, iaaValueLtv);

            }
            if (top10ValueD != 0.0D && oneDayValue > top10ValueD * AD_UNIT_VALUE && iaaValueLtv.isTop10()) {
                AdEventUtil.trackAdEvent(AdEvents.EVENT_TOP10, bundle);
                iaaValueLtv.setTop10(false);
                saveIaaValueLtv(context, iaaValueLtv);

            }
        }
    }

    private static IaaValueLtv getIaaValueLtv(Context context) {
        try {
            String iaaValue = getString(context, PREF_IAA_LTV_VALUE, "");
            IaaValueLtv iaaValueLtv = new Gson().fromJson(iaaValue, IaaValueLtv.class);
            if (iaaValueLtv == null) iaaValueLtv = new IaaValueLtv();
            return iaaValueLtv;
        } catch (Exception e) {
            return new IaaValueLtv();
        }
    }

    private static void saveIaaValueLtv(Context context, IaaValueLtv iaaValueLtv) {
        if (iaaValueLtv != null) {
            saveString(context, PREF_IAA_LTV_VALUE, new Gson().toJson(iaaValueLtv));
        } else {
            remove(context, PREF_IAA_LTV_VALUE);
        }
    }

    private static boolean isSameDay(Context context) {
        long nowTime = System.currentTimeMillis();
        long time = (long) getLong(context, PREF_IAA_LAST_TIME, -1L);
        if (time == -1L) {
            saveLong(context, PREF_IAA_LAST_TIME, nowTime);
            return true;
        }
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String times = sdf.format(new Date(time));
            Date oldDate = sdf.parse(times);
            Calendar oldCalendar = Calendar.getInstance();
            oldCalendar.setTime(oldDate);

            String curDay = sdf.format(new Date());
            Date curDate = sdf.parse(curDay);
            Calendar curCalendar = Calendar.getInstance();
            curCalendar.setTime(curDate);

            if (curCalendar.get(Calendar.YEAR) == oldCalendar.get(Calendar.YEAR)
                    && curCalendar.get(Calendar.MONTH) == oldCalendar.get(Calendar.MONTH)
                    && curCalendar.get(Calendar.DATE) == oldCalendar.get(Calendar.DATE)) {
                return true;
            } else {
                saveLong(context, PREF_IAA_LAST_TIME, nowTime);
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    private static void saveLong(Context context, String key, long value) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putLong(key, value);
        editor.apply();
    }

    private static long getLong(Context context, String key, long defaultValue) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
        return sp.getLong(key, defaultValue);
    }

    private static void saveString(Context context, String key, String value) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString(key, value);
        editor.apply();
    }

    private static String getString(Context context, String key, String defaultValue) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
        return sp.getString(key, defaultValue);
    }

    private static void remove(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.remove(key);
        editor.apply();
    }

    private static void LogTaichiTroasValue(Context context, long iaaValue) {
        double currentImpressionRevenue = ((double) iaaValue / AD_UNIT_VALUE);
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
        float previousTaichiTroasCache = sp.getFloat(PREF_TaichiTroasCache, 0);
        //App本地存储用于累计tROAS的缓存值
        float currentTaichiTroasCache = (float) (previousTaichiTroasCache + currentImpressionRevenue);//累加tROAS的缓存值
        // check是否应该发送TaichitROAS事件
        if (currentTaichiTroasCache >= 0.01) {//如果超过0.01就触发一次tROAS taichi事件
            LogTaichiTroasFirebaseAdRevenueEvent(currentTaichiTroasCache);
            sp.edit().putFloat(PREF_TaichiTroasCache, 0).apply();//重新清零，开始
        } else {
            sp.edit().putFloat(PREF_TaichiTroasCache,
                    currentTaichiTroasCache).apply();//先存着直到超过0.01才发送
        }
    }

    private static void LogTaichiTroasFirebaseAdRevenueEvent(double TaichiTroasCache) {
        Bundle bundle = new Bundle();
        bundle.putDouble("value",
                TaichiTroasCache);//(Required)tROAS事件必须带Double类型的Value
        bundle.putDouble("revenue",
                TaichiTroasCache);//(Required)tROAS事件必须带Double类型的Value
        bundle.putString("currency", "USD");//(Required)tROAS事件必须带Currency的币种，如果是USD的话，就写USD，如果不是USD，务必把其他币种换算成USD
        AdEventUtil.trackAdEvent(AdEvents.EVENT_TOTAL_ADS_REVENUE_001, bundle);
    }
}